package com.salton123.colorflydemo.widget;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.jarvislau.destureviewbinder.GestureViewBinder;
import com.salton123.colorflydemo.R;
import com.salton123.colorflydemo.util.ColorUtils;
import com.salton123.colorflydemo.util.floodfill.IFloodFillMethod;
import com.salton123.colorflydemo.util.floodfill.JniFloodFill;
import com.salton123.log.XLog;
import org.opencv.android.OpenCVLoader;

import java.io.File;
import java.io.FileOutputStream;

/**
 * User: newSalton@outlook.com
 * Date: 2019/5/23 9:58
 * ModifyTime: 9:58
 * Description:
 */
public class MandalaGestureView extends FrameLayout {

    static {
        OpenCVLoader.initDebug();
    }

    public MandalaGestureView(@NonNull Context context) {
        super(context);
        initView();
    }

    public MandalaGestureView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    public MandalaGestureView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }

    private ImageView ivMandala;
    private Bitmap mBitmap;
    private IFloodFillMethod fillMethod;

    /**
     * init view and data
     */
    @SuppressLint("ClickableViewAccessibility")
    public void initView() {
        fillMethod = new JniFloodFill();
        View.inflate(getContext(), R.layout.view_stub_mandala_view_gesture, this);
        ivMandala = findViewById(R.id.ivMandala);
        //设置控件可缩放
        GestureViewBinder.bind(this, ivMandala);
        ivMandala.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (mBitmap == null) {
                    return false;
                }
                int drawableHeight = mBitmap.getHeight();
                int drawableWidth = mBitmap.getWidth();
                final RectF drawableRect = new RectF(0, 0, drawableWidth, drawableHeight);
                ivMandala.setScaleType(ImageView.ScaleType.FIT_CENTER);
                ivMandala.getImageMatrix().mapRect(drawableRect);
                ivMandala.setScaleType(ImageView.ScaleType.FIT_CENTER);
                final int x = (int) event.getX(), y = (int) event.getY();
                float xResult = (x - drawableRect.left)
                        / drawableRect.width();
                float yResult = (y - drawableRect.top)
                        / drawableRect.height();
                int tmpX = (int) (xResult * drawableWidth);
                int tmpY = (int) (yResult * drawableHeight);
                String msg = "contains,x:" + x + ",y:" + y
                        + ",xResult:" + xResult + ",yResult:" + yResult
                        + ",tmpX:" + tmpX + ",tmpY:" + tmpY +
                        ",drawableRect:" + drawableRect;
                XLog.i(MandalaGestureView.this, msg);
                floodFill(tmpX, tmpY, ColorUtils.randomColor());
                return false;
            }
        });
    }

    /**
     * delegate to setImageBitmap
     */
    public void setImageResource(int resId) {
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), resId);
        setImageBitmap(bitmap);
    }

    public void setImageBitmap(Bitmap bitmap) {
        if (bitmap == null) {
            return;
        }
        //只有mutable的图片才可以通过pixel来处理
        if (bitmap.isMutable()) {
            mBitmap = bitmap;
        } else {
            mBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
        }
        if (!bitmap.isRecycled()) {
            bitmap.recycle();
        }
        XLog.i(this, "bitmap.size:" + mBitmap.getAllocationByteCount());
        ivMandala.setImageBitmap(mBitmap);
    }

    public void loadImage(String localFilePath) {
        Bitmap bitmap = BitmapFactory.decodeFile(localFilePath);
        setImageBitmap(bitmap);
    }

    /**
     * flood fill algorithm
     */
    public void floodFill(int tmpX, int tmpY, int color) {

        if (mBitmap != null) {
            if (!isBorderColor(tmpX, tmpY)) {
                fillMethod.floodFill(mBitmap,tmpX,tmpY,color,0);
                ivMandala.setImageBitmap(mBitmap);
            }
        }
    }

    /**
     * prevent border color
     */
    public boolean isBorderColor(int tmpX, int tmpY) {
        if (mBitmap != null) {
            int bitmapWidth = mBitmap.getWidth();
            int bitmapHeight = mBitmap.getHeight();
            if (tmpX < bitmapWidth && tmpY < bitmapHeight && tmpX > 0 && tmpY > 0) {
                int pixel = mBitmap.getPixel(tmpX, tmpY);
                return Color.BLACK == pixel;
            }
        }
        return true;
    }

    public boolean saveBitmap(String savePath) {
        if (mBitmap == null) {
            return false;
        }
        File saveFile = new File(savePath);
        if (!saveFile.exists()) {
            saveFile.getParentFile().mkdirs();
        }
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(savePath);
            mBitmap.compress(Bitmap.CompressFormat.JPEG, 50, fos);
            fos.flush();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

}
